热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

出库管理|零件设计中的状态模式学习心得与应用分析

篇首语:本文由编程笔记#小编为大家整理,主要介绍了设计模式学习笔记之状态模式相关的知识,希望对你有一定的参考价值。 什么是状态模式呢? 允许一个对象在其内部状态改变时改变它的行为。对象看

篇首语:本文由编程笔记#小编为大家整理,主要介绍了设计模式学习笔记之状态模式相关的知识,希望对你有一定的参考价值。


什么是状态模式呢?

允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它的类。。。是不是听起来显示在内部进行零件调换的感觉,其实是有点类似这种想法的,只不过调换的零件就是封装好的状态。

让我们来举个例子




在我还上学的时候,寝室楼下有一台这样的自动贩售机,专门卖饮料。每天晚上寝室关门之后口渴了,在这里面买点饮料喝喝还是很方便的。

下面用程序来模拟一下这个售货机:


可乐售货机类:


/**
*
* 可乐自动贩售机类
* @author birdlove1987
*
*/
public class VendingMachine

//售空
final static int SoldOutState = 0;

//在售
final static int OnReadyState = 1;

//有币
final static int HasCoin = 2;

//出货
final static int SoldState = 3;
//售货机状态
private int state = SoldOutState;

//机内可乐数量
private int count = 0;
//构造函数,初始化自动贩售机
public VendingMachine(int count)

this.count = count;
if (count > 0)
state = OnReadyState;


//向贩售机投币函数
public void insertCoin()

switch (state)

case SoldOutState:
System.out.println("请不要投币了,售货机里已经没有可乐了!");
break;
case OnReadyState:
state = HasCoin;
System.out.println("投币成功,请按出货按钮!");
break;
case HasCoin:
System.out.println("售货机里以及有硬币了,请勿重复投币!");
break;
case SoldState:
System.out.println("正在出货请勿投币!");
break;


//贩售机退币函数
public void returnCoin()

switch (state)

case SoldOutState:
System.out.println("您还没有投币!");
break;
case OnReadyState:
System.out.println("您还没有投币!");
break;
case HasCoin:
System.out.println("请在退币口收好您的硬币");
state = OnReadyState;
break;
case SoldState:
System.out.println("可乐已售出,不能退币");
break;


//按出可乐按钮函数
public void pressButton()

switch (state)

case SoldOutState:
System.out.println("对不起,可乐已售空!");
break;
case OnReadyState:
System.out.println("请您先投币!");
break;
case HasCoin:
System.out.println("请稍等,出可乐中!");
state = SoldState;
appearCola();
break;
case SoldState:
System.out.println("可乐已出,如想再次购买请再次投币!");
break;


//售货机出可乐函数
private void appearCola()

count = count - 1;
System.out.println("出货口,滚出了一瓶可乐!");
if (count > 0)

state = OnReadyState;

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
state = SoldOutState;


//打印目前售货机的状态
public void printState()

switch (state)

case SoldOutState:
System.out.println("=========售空=========");
break;
case OnReadyState:
System.out.println("=========售卖中=========");
break;
case HasCoin:
System.out.println("=========已投币=========");
break;
case SoldState:
System.out.println("=========出货中=========");
break;





写个测试类来测试一下

测试类


/**
* 测试类
* @author birdlove1987
*
*/
public class MainTest
public static void main(String[] args)

//创建售货机实例,并且只放入一瓶可乐
VendingMachine mVendingMachine=new VendingMachine(1);


//打印售货机状态
mVendingMachine.printState();

//投币
mVendingMachine.insertCoin();

//打印售货机状态
mVendingMachine.printState();

//按出货按钮
mVendingMachine.pressButton();


//打印售货机状态
mVendingMachine.printState();

//投币
mVendingMachine.insertCoin();

//打印售货机状态
mVendingMachine.printState();

//按出货按钮
mVendingMachine.pressButton();

//打印售货机状态
mVendingMachine.printState();






嗯!模拟成功了!好像感觉还不错呢!不过买了一段时间,你可能发现,如果不搞一些促销活动,更本就搞不过那些有促销的商家!




所以自动售货机也要搞一个“再来一瓶”的活动啊!

但是!!!如果现在直接在自动售货机的类上去直接修改,就违背了软件设计里的“开-闭原则”了,破坏了我们已经闭合的类。所以现在看来,这种设计并不好。。

下面就轮到状态设计模式登场啦,我们从新构建类,这次以状态为类,来构建。

首先定义一下状态接口


/***
* 状态接口
* @author birdlove1987
*
*/
public interface State

//投币函数
public void insertCoin();

//退币函数
public void returnCoin();

//按出可乐按钮函数
public void pressButton();

//出可乐函数
public void appearCola();

//打印状态函数
public void printState();




再来定义状态类


/***
* 在售状态类
* @author birdlove1987
*
*/
public class OnReadyState implements State

//贩售机引用
private VendingMachine mVendingMachine;

//构造函数初始化
public OnReadyState(VendingMachine mVendingMachine)

this.mVendingMachine=mVendingMachine;


@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("投币成功,请按出货按钮!");
mVendingMachine.setState(mVendingMachine.mHasCoin);

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("您还没有投币!");


@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请您先投币!");


@Override
public void appearCola()

// TODO Auto-generated method stub

@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========售卖中=========");

/***
* 售空状态类
* @author birdlove1987
*
*/
public class SoldOutState implements State
private VendingMachine mVendingMachine;
public SoldOutState(VendingMachine mCandyMachine)

this.mVendingMachine=mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("请不要投币了,售货机里已经没有可乐了!");


@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out
.println("您还没有投币!");

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("对不起,可乐已售空!");


@Override
public void appearCola()

// TODO Auto-generated method stub

@Override
public void printState()
// TODO Auto-generated method stub
System.out.println("=========售空=========");



/***
* 已投币状态类
* @author birdlove1987
*
*/
public class HasCoin implements State

private VendingMachine mVendingMachine;
public HasCoin(VendingMachine mVendingMachine)

this.mVendingMachine = mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("售货机里以及有硬币了,请勿重复投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("请在退币口收好您的硬币");
mVendingMachine.setState(mVendingMachine.mOnReadyState);

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请稍等,出可乐中!");

//创建随机中奖概率
Random anotherOne = new Random();

//20%的机会再来一瓶
int luck = anotherOne.nextInt(5);
if(luck==0)

mVendingMachine.setState(mVendingMachine.mOneMoreCola);
else

mVendingMachine.setState(mVendingMachine.mSoldState);


@Override
public void appearCola()


@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========已投币=========");

/**
* 出可乐状态类
* @author birdlove1987
*
*/
public class SoldState implements State
private VendingMachine mVendingMachine;
public SoldState(VendingMachine mVendingMachine)

this.mVendingMachine=mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("正在出货请勿投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("可乐已售出,不能退币");


@Override
public void pressButton()

// TODO Auto-generated method stub
System.out
.println("可乐已出,如想再次购买请再次投币!");

@Override
public void appearCola()

// TODO Auto-generated method stub

mVendingMachine.appearCola();
if (mVendingMachine.getCount() > 0)

mVendingMachine.setState(mVendingMachine.mOnReadyState);

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
mVendingMachine.setState(mVendingMachine.mSoldOutState);



@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========出货中=========");


/***
* 再来一瓶类
* @author birdlove1987
*
*/
public class OneMoreCola implements State
private VendingMachine mVendingMachine;
public OneMoreCola(VendingMachine mVendingMachine)

this.mVendingMachine = mVendingMachine;

@Override
public void insertCoin()

// TODO Auto-generated method stub
System.out.println("正在出货请勿投币!");

@Override
public void returnCoin()

// TODO Auto-generated method stub
System.out.println("可乐已售出,不能退币");

@Override
public void pressButton()

// TODO Auto-generated method stub
System.out.println("请稍等,出可乐中!");

@Override
public void appearCola()

// TODO Auto-generated method stub

mVendingMachine.appearCola();
if (mVendingMachine.getCount() == 0)

mVendingMachine.setState(mVendingMachine.mSoldOutState);

else

System.out.println("恭喜你获得了再来一瓶,马上为您再出一瓶可乐");
mVendingMachine.appearCola();
if (mVendingMachine.getCount() > 0)

mVendingMachine.setState(mVendingMachine.mOnReadyState);

else

System.out.println("对不起,可乐已经售空了,请勿在投币!");
mVendingMachine.setState(mVendingMachine.mSoldOutState);



@Override
public void printState()

// TODO Auto-generated method stub
System.out.println("=========再来一瓶=========");





构建自动贩售机类


/**
* 自动售货机类
* @author birdlove1987
*
*/
public class VendingMachine
//状态类引用
State mSoldOutState;
State mOnReadyState;
State mHasCoin;
State mSoldState;
State mOneMoreCola;

//目前状态
private State state;

//可乐计数器
private int count = 0;
//构造函数
public VendingMachine(int count)

this.count = count;
mSoldOutState = new SoldOutState(this);
mOnReadyState = new OnReadyState(this);
mHasCoin = new HasCoin(this);
mSoldState = new SoldState(this);
mOneMoreCola = new OneMoreCola(this);
if (count > 0)

state = mOnReadyState;

else

state = mSoldOutState;


//设置状态函数
public void setState(State state)

this.state = state;

//投币函数
public void insertCoin()

state.insertCoin();


//退币函数
public void returnCoin()

state.returnCoin();


//按出可乐按钮函数
public void pressButton()

state.pressButton();
state.appearCola();

//出可乐函数
void appearCola()

// TODO Auto-generated method stub
if (count > 0)

count = count - 1;
System.out.println("出货口,滚出了一瓶可乐!");


//可乐计数函数
public int getCount()

return count;


//打印状态函数
public void printState()

state.printState();




最后写一个测试类测试一下


/**
* 测试类
* @author birdlove1987
*
*/
public class MainTest
public static void main(String[] args)


//实例化自动贩售机对象
VendingMachine mVendingMachine = new VendingMachine(10);

//打印状态
mVendingMachine.printState();
//投币
mVendingMachine.insertCoin();

//打印状态
mVendingMachine.printState();
//按出可乐按钮
mVendingMachine.pressButton();
//打印状态
mVendingMachine.printState();
//投币
mVendingMachine.insertCoin();

//打印状态
mVendingMachine.printState();
//按出可乐按钮
mVendingMachine.pressButton();
//打印状态
mVendingMachine.printState();









卧槽!一次都没中奖,什么鬼!!!不行,买买买!!!




中了一次。。。好吧,我来作弊一下。。调到100%




哈哈哈!


状态模式的优点
    1.状态模式将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
    2.将与状态有关的行为封装到一个类中,方便地增加新的状态,只需改变对象状态即可改变对象的行为。 
    3.提供代码复用性,降低了程序的某些耦合性。   
     
状态模式的缺点
    1.有时候状态类会很多,而且逻辑复杂。

状态模式适用场景
    1、对象的行为依赖于它的状态,并且其行为依据它的状态改变而改变。 
    2、代码中包含大量与对象状态有关的条件语句









推荐阅读
author-avatar
Lai-flip_179
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有